Technical debt thrives particularly well in environments with certain characteristics. Lack of experience in software development within a team and missing awareness of the importance of good, easy-to-understand code are for example strong drivers. Too much pressure to implement features fast, as well as too much bureaucracy that discourages individual initiative, are other contributors that impact a team and quickly result in technical debt.
In a nutshell, people, their skills and their cooperation within and across a team are the key factors for the build-up but also the reduction of technical debt. That’s where we need to start.
In the following, we describe seven principles that have helped to deal with technical debt more effectively.
-
Creating the necessary awareness. Technical debt is ubiquitous [1]. It is essential to be aware of this. Although many developers have a good sense of technical debt, the perception of urgency and severity of a problem is different for everyone. In addition, not all technical debt is the same. There is technical debt that has a greater impact on day-to-day work than other.
In order for technical debt reduction to work, it is essential that everyone on the team, from developers to product management, is aware of the issues and their impact on daily work. This is the only way to jointly decide which technical dept needs to be addressed urgently and which can wait.
-
Stop adding shit to the pile. When technical debt is a big problem, one of the first and most effective steps to improve the situation is to create as little new technical debt as possible. This is easier said than done. Particularly when high levels of technical debt have already been built up, they often force you to take new detours when it comes to further developments.
In my opinion, Fowler’s principle applies here: Adapt your code through refactorings so that the planned changes can be easily (or at least more easily) implemented. But even that can be difficult or impossible. In such cases, you have to decide whether the feature should be implemented as soon as possible or whether you have to wait until the corresponding component has been refactored.
-
Supporting the team to write better code. The build-up (and reduction) of technical debt depends heavily on the experience, knowledge and attitude of the developers. Code reviews in teams and pair programming can help to build a common understanding of good code. Even if such measures reduce the development speed in the beginning, they are, in our experience, essential for sharing knowledge and developing a common understanding. All this pays off in the long run through higher code quality and faster development cycles.
-
Establish clear and useful technical guidelines. Useful guidelines can also help improve code quality in the long run. The emphasis here is on useful. Many guidelines are boring documents of, at best, semi-interesting things. In particular, useful guidelines describe in-house solutions to recurring problems and issues that all developers encounter in their daily work. A simple example is the preferred structure/implementation of a REST API. Ideally, these guidelines are easy to find so that solutions to a specific problem or question can be found quickly, e.g. via an in-house StackOverflow.
-
Focus on the biggest pain points. Not all technical debt is equal. Some have a strong impact on day-to-day work, while others have little effect. That’s why it’s important to focus on eliminating the biggest pain points from the start. With a simple “effort/benefit” matrix, it is relatively easy to determine which technical dept causes particularly high pain and is quite easy to eliminate. It is a good idea to start with refactorings that offer a high benefit with relatively little effort. Every refactoring, every action you take to remove bad code, then brings an immediate improvement. If you can manage that, you also have a good chance to provide overall relief soon.
-
At the beginning, keep refactorings simple. It’s tempting to tackle the biggest issues right away and knock everything over. This is usually not a good idea. Especially at the beginning, it is important to first get a feeling for the procedure and the effort involved. That’s why, in our experience, it’s good to start with something relatively simple but useful and improve that. While doing this, the team will already learn a lot. From there, you can move forward and tackle bigger problems. Initial achievements provide confidence and accelerate the process over time.
-
Accepting limits. Solving all problems in a system is impossible in most cases and, above all, does not make sense at all. The Pareto principle applies here: 20% of the technical debt causes 80% of the pain in daily work. In most cases, it is quite sufficient to address the central 20% of technical debt. Additionally, it is helpful to set clear boundaries and accept that certain technical debt will not be reduced for the time being. This is especially important when communicating with and among developers in order to establish clear expectations.
The reduction of technical debt is not a one-time activity, but a process that accompanies software development in the long run. Unfortunately, it is in the nature of technical dept that new debt is continuously created [1] and some can only be reduced in the long term. As a consequence:
Nevertheless, especially with a topic like technical debt, it is important to celebrate the (small) victories, to consciously recognize the improvements and to enjoy the journey 🙂 This is the only way to build up the necessary momentum and also to maintain it in the long term.